package ctrhost

import (
    "github.com/astaxie/beego/logs"
    "strings"
    "fmt"
    "time"
    "cloud_worm/util/umodels/mysqldb"
    "cloud_worm/util/umodels/mysqldb/dbtask"
    "cloud_worm/util/umodels/mysqldb/dbmanager"
    "cloud_worm/util/uhttp"
    "cloud_worm/util/uid"
    "cloud_worm/wormweb/controllers/ctrutil"
    "cloud_worm/wormweb/controllers/ctrconfig"
)

type ApplyWeaponTaskController struct {
    ctrconfig.LoginCtr
}

/**
 @Description：处理输入apply_name为具体应用名的操作
 @Param:
 @Return：
    error           发生错误，并回复http request
    nil             成功，未回复
 */
func (a *ApplyWeaponTaskController) oneApplyMachineTask(targetName string, taskWps []string, comment string) (*dbtask.WeaponTask, error) {

    // 匹配application
    application := &dbmanager.Application{Name: targetName}
    err := application.Read("name")
    if err != nil {
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr,"input application name.", data)
        a.ServeJSON()
        return nil, fmt.Errorf("input application name error: %s", err.Error())
    }

    // 准备主机host
    mach := &dbmanager.Machine{ApplyId: application.Id}
    machineSize, err := mach.Count(mysqldb.StatusValid, application.Id, mysqldb.SelectStrAll, mysqldb.SelectStrAll)
    if err != nil {
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input apply name for select error.", data)
        a.ServeJSON()
        return nil, fmt.Errorf("the input apply name for select error: %s", err.Error())
    }

    // 准备插入insert
    task := &dbtask.WeaponTask{
        TaskId:      uid.TaskIdProducer().CreateTaskId(),
        TaskOwner:   a.UserInfo.Username,
        TargetType:  ctrutil.TaskForApplication,
        Target:      application.Name,
        WeaponsName: strings.Join(taskWps, ","),
        Comment:     comment,
        SumCount:    int(machineSize) * len(taskWps),
        Created:     time.Now().Unix(),
        Status:      ctrutil.WEAPON_TASK_NO_DO,
    }
    task.Updated = task.Created

    err = task.Insert()
    if err != nil {
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "insert task error.", data)
        a.ServeJSON()
        return nil, fmt.Errorf("insert task error: %s", err.Error())
    }

    return task, nil
}

/**
 @Description：处理输入apply_name为all的情况，表示所有机器
 @Param:
 @Return：
 */
func (a *ApplyWeaponTaskController) allMachineTask(taskWps []string, comment string) (*dbtask.WeaponTask, error) {

    wolId := dbmanager.WormId{}
    onlineCount, err := wolId.CountStatus(dbmanager.AgentOnline, ctrutil.RunMode)
    if err != nil {
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "select online count failed.", data)
        a.ServeJSON()
        return nil, fmt.Errorf("select online count failed: %s", err.Error())
    }

    // 准备插入insert
    task := &dbtask.WeaponTask{
        TaskId:      uid.TaskIdProducer().CreateTaskId(),
        TaskOwner:   a.UserInfo.Username,
        TargetType:  ctrutil.TaskForAll,
        Target:      ctrutil.TaskAllApplication,
        WeaponsName: strings.Join(taskWps, ","),
        Comment:     comment,
        SumCount:    int(onlineCount) * len(taskWps),
        Created:     time.Now().Unix(),
        Status:      ctrutil.WEAPON_TASK_NO_DO,
    }
    task.Updated = task.Created

    err = task.Insert()
    if err != nil {
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "insert task error.", data)
        a.ServeJSON()
        return nil, fmt.Errorf("insert task error: %s", err.Error())
    }

    return task, nil
}

// 创建check task
func (a *ApplyWeaponTaskController) Create()  {
    a.Manager()

    type InputInfo struct {
        Comment         string      `json:"comment"`
        ApplyName       string      `json:"apply_name"`         // 必填，
        Weapons         string      `json:"weapons"`            // 必填，涉及的weapon，采用","号分割，weapon name
    }
    var input InputInfo
    if err := a.Unmarshal(&input); err != nil {
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, err.Error(), nil)
        a.ServeJSON()
        return
    }

    if input.ApplyName == mysqldb.SelectStrAll {
        logs.Warn("input apply name error.")
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input apply name error.", data)
        a.ServeJSON()
        return
    }
    var taskWps []string
    for _, item := range strings.Split(strings.TrimSpace(input.Weapons), ",") {
        item = strings.TrimSpace(item)
        if item != "" {
            taskWps = append(taskWps, item)
        }
    }
    if len(taskWps) == 0 {
        logs.Warn("no input weapon")
        data := map[string]interface{}{"total": 0, "data": []dbtask.WeaponTask{}}
        a.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "no input weapon", data)
        a.ServeJSON()
        return
    }

    // 任务创建
    var task *dbtask.WeaponTask
    var err error
    if input.ApplyName != ctrutil.TaskAllApplication {
        task, err = a.oneApplyMachineTask(input.ApplyName, taskWps, input.Comment)
        if err != nil {
            // 异常已经回复
            logs.Error(err.Error())
            return
        }
    } else {
        task, err = a.allMachineTask(taskWps, input.Comment)
        if err != nil {
            // 异常已经回复
            logs.Error(err.Error())
            return
        }
    }

    // 成功插入之后的结果返回
    var tasks []dbtask.WeaponTask
    tasks = append(tasks, *task)
    data := map[string]interface{}{"total": 1, "data": tasks}
    a.Data["json"] = uhttp.CreateOkResponse(data)
    a.ServeJSON()
    return
}
